﻿using System;
using Microsoft.Exchange.WebServices.Data;
using BodyType = Microsoft.Exchange.WebServices.Data.BodyType;
using System.Data;
using System.Collections.Generic;

namespace JL.LiveAtEdu.Helpers
{
    public class Messages
    {
        #region Count Messages
        /// <summary>
        /// Counts the messages inbox.
        /// </summary>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="IsRead">if set to <c>true</c> [is read].</param>
        /// <returns></returns>
        public static int CountMessagesInbox(int pageSize, bool IsRead)
        {
            ItemView view = new ItemView(pageSize, 0);
            SearchFilter sf = IsRead == true ?
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true) :
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
            FindItemsResults<Item> findResults = Bind.MeIn().FindItems(WellKnownFolderName.Inbox, sf, view);
            return findResults.Items.Count;
        }


        /// <summary>
        /// Counts the messages outbox.
        /// </summary>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="IsRead">if set to <c>true</c> [is read].</param>
        /// <returns></returns>
        public static int CountMessagesOutbox(int pageSize, bool IsRead)
        {
            ItemView view = new ItemView(pageSize, 0);
            SearchFilter sf = IsRead == true ?
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true) :
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
            FindItemsResults<Item> findResults = Bind.MeIn().FindItems(WellKnownFolderName.Outbox, sf, view);
            return findResults.Items.Count;
        }


        /// <summary>
        /// Counts the messages deleted.
        /// </summary>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="IsRead">if set to <c>true</c> [is read].</param>
        /// <returns></returns>
        public static int CountMessagesDeleted(int pageSize, bool IsRead)
        {
            ItemView view = new ItemView(pageSize, 0);
            SearchFilter sf = IsRead == true ?
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true) :
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
            FindItemsResults<Item> findResults = Bind.MeIn().FindItems(WellKnownFolderName.DeletedItems, sf, view);
            return findResults.Items.Count;
        }

        /// <summary>
        /// Counts the messages sent.
        /// </summary>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="IsRead">if set to <c>true</c> [is read].</param>
        /// <returns></returns>
        public static int CountMessagesSent(int pageSize, bool IsRead)
        {
            ItemView view = new ItemView(pageSize, 0);
            SearchFilter sf = IsRead == true ?
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true) :
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
            FindItemsResults<Item> findResults = Bind.MeIn().FindItems(WellKnownFolderName.SentItems, sf, view);
            return findResults.Items.Count;
        }
        #endregion

        #region Get Messages

        #region List Messages from folder Class
        public class InboxReceived
        {
            public string Id;
            public string Subject;
            public string DateReceived;
            public string IsRead;
            public string SentByName;
            public string SentByAddress;

            public InboxReceived()
            {
            }

            public InboxReceived(string Id, string Subject, string DateReceived,
            string IsRead, string SentByName, string SentByAddress)
            {
                this.Id = Id;
                this.Subject = Subject;
                this.DateReceived = DateReceived;
                this.IsRead = IsRead;
                this.SentByName = SentByName;
                this.SentByAddress = SentByAddress;
            }
        }
        #endregion


        /// <summary>
        /// Gets the inbox received messages list.
        /// </summary>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="IsRead">if set to <c>true</c> [is read].</param>
        /// <returns></returns>
        public static DataTable GetInboxReceivedMessagesList(int pageSize, bool IsRead)
        {
            ItemView view = new ItemView(pageSize, 0);
            SearchFilter sf = IsRead == true ?
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true) :
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
            FindItemsResults<Item> findResults =
            Bind.MeIn().FindItems(WellKnownFolderName.Inbox, sf, view);

            DataTable dt = new DataTable();
            dt.Columns.Add("ID", typeof(string));
            dt.Columns.Add("Subject", typeof(string));
            dt.Columns.Add("DateReceived", typeof(string));
            dt.Columns.Add("IsRead", typeof(string));
            dt.Columns.Add("SentByName", typeof(string));
            dt.Columns.Add("SentByAddress", typeof(string));

            foreach (Item item in findResults.Items)
            {
                Item mess = Item.Bind(Bind.MeIn(), item.Id.UniqueId);
                EmailMessage message = mess as EmailMessage;

                dt.Rows.Add(item.Id.UniqueId,
                message.Subject,
                item.DateTimeReceived.ToShortDateString(),
                message.IsRead ? "1" : "0",
                message.From.Name,
                message.From.Address);
            }
            return dt;
        }

        /// <summary>
        /// Gets the inbox received messages list from list.
        /// </summary>
        /// <param name="pageSize">Size of the page.</param>
        /// <param name="IsRead">if set to <c>true</c> [is read].</param>
        /// <returns></returns>
        public static List<InboxReceived> GetInboxReceivedMessagesListFromList(int pageSize, bool IsRead)
        {
            List<InboxReceived> lst = new List<InboxReceived>();

            ItemView view = new ItemView(pageSize, 0);
            SearchFilter sf = IsRead == true ?
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, true) :
            new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false);
            FindItemsResults<Item> findResults =
            Bind.MeIn().FindItems(WellKnownFolderName.Inbox, sf, view);


            foreach (Item item in findResults.Items)
            {
                Item mess = Item.Bind(Bind.MeIn(), item.Id.UniqueId);
                EmailMessage message = mess as EmailMessage;

                lst.Add(new InboxReceived(item.Id.UniqueId, message.Subject,
                item.DateTimeReceived.ToShortDateString(), message.IsRead ? "1" : "0",
                message.From.Name, message.From.Address));
            }
            return lst;
        }

        /// <summary>
        /// Gets the message HTML with in line attachments.
        /// </summary>
        /// <param name="messId">The mess id.</param>
        /// <returns></returns>
        public static string GetMessageHtmlWithInLineAttachments(string messId)
        {
            PropertySet psPropSet = new PropertySet(BasePropertySet.FirstClassProperties) {
            RequestedBodyType = BodyType.HTML };
            Item mess = Item.Bind(Bind.MeIn(), messId, psPropSet);
            mess.Body.BodyType = BodyType.HTML;

            string sHTMLCOntent = mess.Body.Text;

            FileAttachment[] attachments = null;

            if (mess.Attachments.Count != 0)
            {
                attachments = new FileAttachment[mess.Attachments.Count];
                for (int i = 0; i < mess.Attachments.Count; i++)
                {
                    try
                    {
                        if (mess.Attachments[i].IsInline)
                        {
                            string sType = mess.Attachments[i].ContentType.ToLower();
                            if (sType.Contains("image"))
                            {
                                attachments[i] = (FileAttachment)mess.Attachments[i];
                                attachments[i].Load();
                                string sId = attachments[i].ContentId;
                                sType = sType.Replace("image/", "");
                                string oldString = "cid:" + sId;
                                string imagem =
                                Convert.ToBase64String(attachments[i].Content);
                                sHTMLCOntent = sHTMLCOntent.Replace(oldString,
                                String.Format("data:image/{0};base64,{1}", sType, imagem));
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        return ex.Message;
                    }
                }
            }
            return sHTMLCOntent;
        }

        /// <summary>
        /// Sends the new message.
        /// </summary>
        /// <param name="service">The service.</param>
        /// <param name="subject">The subject.</param>
        /// <param name="body">The body.</param>
        /// <param name="mailTo">The mail to.</param>
        /// <param name="mailCc">The mail cc.</param>
        /// <param name="mailBcc">The mail BCC.</param>
        /// <param name="attachments">The attachments.</param>
        /// <returns></returns>
        public static bool SendNewMessage(ExchangeService service,
        string subject, string body,
        List<string> mailTo,
        List<string> mailCc,
        List<string> mailBcc,
        List<string> attachments)
        {
            // Create an e-mail message and identify the Exchange service.
            EmailMessage message = new EmailMessage(service) {
            /* Subject*/
            Subject = subject, /* Body*/
            Body = new MessageBody(body) };

            // Recipients
            foreach (string recipientes in mailTo)
            {
                message.ToRecipients.Add(recipientes);
            }

            // Recipients
            foreach (string recipientes in mailCc)
            {
                message.CcRecipients.Add(recipientes);
            }

            // Recipients
            foreach (string recipientes in mailBcc)
            {
                message.BccRecipients.Add(recipientes);
            }

            // Attachments
            foreach (string att in attachments)
            {
                message.Attachments.AddFileAttachment(att);
            }
            // Send the mail. This makes a trip to the EWS server.
            message.SendAndSaveCopy();
            return true;
        }
        #endregion
    }
}
